//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<XForm.h>
///	@path	~/src/gui/xgui/
///	@date	2008/05/23
///	@desc	.

#pragma once

#include "xeres.h"

#include <deque>
#include <set>

#include "lib/utilities/time.h"

#include "gui/IGuiForm.h"

namespace xeres {

	// forward declaration
	class Composition;

	/*! 
		\class	XForm
		\brief	General form contains gui components.
	*/
	class XForm : public IGuiForm
	{
	public:

		/// \ctor
		XForm( void );

		/// \ctor
		XForm( const Rect<int>& placement );

		/// \ctor
		XForm( const Pair<int>& size );

		/// \dtor
		virtual ~XForm( void );

		DECL_IOBJECT_CLASS_DYNAMIC( XForm , IGuiForm );

	public:

		/// \name XGui Component Attributes
		//@{

		/// \brief	Set size of component.
		virtual bool SetSize( const Pair<int>& size );

		/// \brief	Set size of component and adaptive size by children.
		virtual bool SetAdptiveSize( const Pair<int>& size );

		/// \brief	Set parent component.
		virtual bool SetParent( RefWeak<IGuiForm> parent );

		//@}

		/// \name Message Passing
		//@{

		///	\brief	Process key input message.
		virtual HandleInput OnKeyInput( Updater& updater );

		///	\brief	Process mouse input message.
		virtual HandleInput OnMouseInput( Updater& updater );

		/// \brief	Call when mouse enter component.
		virtual void OnMouseEnter( Updater& updater , RefWeak<IGuiComp> last );

		/// \brief	Call when mouse leave component.
		virtual void OnMouseLeave( Updater& updater , RefWeak<IGuiComp> next );

		/// \brief	Call when focus in.
		virtual void OnFocusIn( Updater& updater , RefWeak<IGuiComp> last );

		/// \brief	Call when focus out.
		virtual void OnFocusOut( Updater& updater , RefWeak<IGuiComp> next );

		/// \brief	Call when mouse hover component.
		virtual void OnMouseHover( Updater& updater );

		/// \brief	Call when close window.
		virtual void OnClose( void );

		//@}

		/// \name Presentation Manipulation
		//@{

		/// \brief	Tick update.
		virtual void Tick( Updater& updater , float dTime );

		/// \brief	Draw XGUI component to composition.
		virtual void Draw( Composition& composition );

		//@}

		/// \name XGUI Form Interface
		//@{

		/// \brief	Clear focus.
		virtual void ClearFocus( Updater& updater );

		/// \brief	Only clear focus.
		virtual void ClearFocus( void );

		///	\brief	Get focus component.
		virtual RefWeak<IGuiComp> GetFocusing( void );

		/// \brief	Enter input mode.
		virtual void EnterInputMode( RefWeak<IGuiComp> comp , Updater& updater );

		/// \brief	Get input mode.
		virtual bool GetInputMode( void );

		/// \brief	Add child component.
		virtual bool AddChild( RefWeak<IGuiComp> comp );

		/// \brief	Del child component.
		virtual bool DelChild( RefWeak<IGuiComp> comp );

		/// \brief	Get child by index.
		virtual RefWeak<IGuiComp> GetChild( int index );

		/// \brief	Add tickable child.
		virtual void AddTickable( RefWeak<IGuiComp> comp );

		/// \brief	Del tickable child.
		virtual void DelTickable( RefWeak<IGuiComp> comp );

		/// \brief	IsTickable
		virtual bool IsTickable( void );

		/// \brief	Request focus.
		virtual void RequestFocus( RefWeak<IGuiComp> comp , Updater& updater );

		/// \brief	Request focus only.
		virtual void RequestFocus( RefWeak<IGuiComp> comp );

		/// \brief	Request update.
		virtual void RequestUpdate( RefWeak<IGuiComp> comp , const Rect<int>& region );

		/// \brief	Request show component.
		virtual void RequestShow( RefWeak<IGuiComp> comp , bool show );

		/// \brief	Set capturing component.
		virtual void SetCapture( RefWeak<IGuiComp> comp );

		/// \brief	Get capturing component.
		virtual RefWeak<IGuiComp> GetCapture( void );

		/// \brief	Release capture.
		virtual void ReleaseCapture( void );

		//@}

		/// \name	Local Methods
		//@{

		/// \brief	Cycle focus component.
		void CycleFocus( bool forward , Updater& updater );

		/// \brief	Get component at point.
		RefWeak<IGuiComp> GetAtPoint( const Pair<int>& point , bool enableMatch , bool visibleMatch );

		/// \brief	Set offset.
		void SetOffset( const Pair<int>& offset );

		/// \brief	Get offset.
		const Pair<int>& GetOffset( void ) const;

		//@}

	protected:

		/// \brief	Draw background.
		virtual void OnDrawBackground( Composition& composition );

		//// \brief	Re-order children.
		virtual void ReorderChildren( void );

		//@ data

		// focusing control
		RefWeak<IGuiComp>				m_focusing;

		// capturing control
		RefWeak<IGuiComp>				m_capturing;

		// mouse hovering control
		RefWeak<IGuiComp>				m_hovering;

		// scroll offset
		Pair<int>						m_offset;

		// children components
		std::deque< Ref<IGuiComp> >		m_children;

		// tickable components
		std::set< RefWeak<IGuiComp> >	m_tickable;

		// last mouse move
		Time							m_lastMove;

		// form states
		bool							m_inputMode;
		bool							m_spare0[3];

		// events
		function<void()>				m_messageCall;
	};

} // namespace xeres
